package com.gitee.wsl.mathematics.function.noise.d2

import com.gitee.wsl.mathematics.function.noise.Noise2d
import kotlin.random.Random

class MultiPerlin2d(iterations: Int, baseFreq: Int, seed: Int = 19937, tableSz: Int = 1024) :
    Noise2d {

    private val perlins = mutableListOf<PerlinNoise2d>()

    init {
        val rand = Random(seed)
        var freq = baseFreq
        for (i in 0 until iterations) {
            perlins += PerlinNoise2d(rand.nextInt(), tableSz).apply {
                tileSizeX = freq
                tileSizeY = freq
            }
            freq *= 2
        }
    }

    override fun eval(x: Float, y: Float): Float {
        var f = 0f
        var amplitude = 1f
        for (i in perlins.indices) {
            val p = perlins[i]
            f += p.eval(x * p.tileSizeX, y * p.tileSizeY) * amplitude
            amplitude *= 0.5f
        }
        return f
    }
}

fun Noise2d.Companion.multiPerlin(iterations: Int,
                              baseFreq: Int,
                              seed: Int = 19937,
                              tableSz: Int = 1024) = MultiPerlin2d(iterations, baseFreq, seed, tableSz)